import sys
import os
import re
import hashlib
import random
import time
from collections import Counter
import pandas as pd
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                             QHBoxLayout, QListWidget, QLabel, QPushButton, 
                             QTextEdit, QFileDialog, QMessageBox, QProgressBar,
                             QLineEdit, QDialog, QFormLayout, QDialogButtonBox)
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtGui import QDragEnterEvent, QDropEvent
import PyPDF2
from openpyxl import load_workbook
import requests

class ConfigDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("API设置")
        self.setModal(True)
        self.initUI()
        
    def initUI(self):
        layout = QFormLayout()
        
        self.app_id_edit = QLineEdit()
        self.app_key_edit = QLineEdit()
        
        layout.addRow("百度翻译APP ID:", self.app_id_edit)
        layout.addRow("百度翻译密钥:", self.app_key_edit)
        
        buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        
        layout.addRow(buttons)
        self.setLayout(layout)
        
    def get_config(self):
        return self.app_id_edit.text(), self.app_key_edit.text()
        
    def set_config(self, app_id, app_key):
        self.app_id_edit.setText(app_id)
        self.app_key_edit.setText(app_key)

class TranslationThread(QThread):
    progress_updated = pyqtSignal(int)
    translation_finished = pyqtSignal(list)
    
    def __init__(self, word_list, app_id, app_key):
        super().__init__()
        self.word_list = word_list
        self.app_id = app_id
        self.app_key = app_key
        
    def run(self):
        results = []
        total_words = len(self.word_list)
        
        for i, (word, count) in enumerate(self.word_list):
            try:
                # 使用百度翻译API
                translation = self.baidu_translate(word)
                results.append((word, translation, count))
            except Exception as e:
                results.append((word, f"翻译错误: {str(e)}", count))
            
            # 更新进度
            progress = int((i + 1) / total_words * 100)
            self.progress_updated.emit(progress)
            
            # 添加延迟，避免请求过于频繁
            time.sleep(0.1)
        
        self.translation_finished.emit(results)
    
    def baidu_translate(self, text, from_lang='en', to_lang='zh'):
        if not self.app_id or not self.app_key:
            raise Exception("请先配置百度翻译API")
            
        # 生成签名
        salt = str(random.randint(32768, 65536))
        sign = self.app_id + text + salt + self.app_key
        sign = hashlib.md5(sign.encode()).hexdigest()
        
        # 构建请求
        url = "http://api.fanyi.baidu.com/api/trans/vip/translate"
        params = {
            'q': text,
            'from': from_lang,
            'to': to_lang,
            'appid': self.app_id,
            'salt': salt,
            'sign': sign
        }
        
        # 发送请求
        response = requests.get(url, params=params)
        result = response.json()
        
        # 检查错误
        if 'error_code' in result:
            error_msg = result.get('error_msg', '未知错误')
            raise Exception(f"API错误: {error_msg}")
        
        # 提取翻译结果
        if 'trans_result' in result:
            return result['trans_result'][0]['dst']
        else:
            raise Exception("未找到翻译结果")

class FileDropWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):
        self.setAcceptDrops(True)
        
        layout = QVBoxLayout()
        
        self.label = QLabel("拖放文件到这里 (PDF, TXT, Excel)")
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setStyleSheet("""
            QLabel {
                border: 2px dashed #aaa;
                border-radius: 10px;
                padding: 20px;
                background-color: #f9f9f9;
                font-size: 14px;
            }
        """)
        
        self.file_list = QListWidget()
        
        self.clear_btn = QPushButton("清空列表")
        self.clear_btn.clicked.connect(self.file_list.clear)
        
        self.process_btn = QPushButton("处理文件")
        
        layout.addWidget(self.label)
        layout.addWidget(self.file_list)
        layout.addWidget(self.clear_btn)
        layout.addWidget(self.process_btn)
        
        self.setLayout(layout)
        
    def dragEnterEvent(self, event: QDragEnterEvent):
        if event.mimeData().hasUrls():
            event.acceptProposedAction()
            
    def dropEvent(self, event: QDropEvent):
        files = [url.toLocalFile() for url in event.mimeData().urls()]
        valid_extensions = ['.pdf', '.txt', '.xlsx', '.xls']
        
        for file in files:
            if any(file.lower().endswith(ext) for ext in valid_extensions):
                self.file_list.addItem(file)
        
        event.acceptProposedAction()

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.app_id = ""
        self.app_key = ""
        self.initUI()
        self.words_counter = Counter()
        
    def initUI(self):
        self.setWindowTitle("文件英文提取与翻译工具")
        self.setGeometry(100, 100, 900, 600)
        
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        layout = QHBoxLayout()
        
        # 左侧文件拖放区域
        self.file_drop_widget = FileDropWidget()
        self.file_drop_widget.process_btn.clicked.connect(self.process_files)
        
        # 右侧结果显示区域
        right_panel = QVBoxLayout()
        
        self.result_text = QTextEdit()
        self.result_text.setPlaceholderText("处理结果将显示在这里...")
        
        self.progress_bar = QProgressBar()
        self.progress_bar.setVisible(False)
        
        button_layout = QHBoxLayout()
        self.export_btn = QPushButton("导出到Excel")
        self.export_btn.clicked.connect(self.export_to_excel)
        self.export_btn.setEnabled(False)
        
        self.settings_btn = QPushButton("API设置")
        self.settings_btn.clicked.connect(self.show_settings)
        
        button_layout.addWidget(self.export_btn)
        button_layout.addWidget(self.settings_btn)
        
        right_panel.addWidget(QLabel("处理结果:"))
        right_panel.addWidget(self.result_text)
        right_panel.addWidget(self.progress_bar)
        right_panel.addLayout(button_layout)
        
        layout.addWidget(self.file_drop_widget, 1)
        layout.addLayout(right_panel, 2)
        
        central_widget.setLayout(layout)
        
        self.translation_thread = None
        self.translation_results = []
        
        # 尝试加载保存的配置
        self.load_config()
        
    def load_config(self):
        try:
            if os.path.exists("config.txt"):
                with open("config.txt", "r") as f:
                    lines = f.readlines()
                    if len(lines) >= 2:
                        self.app_id = lines[0].strip()
                        self.app_key = lines[1].strip()
        except:
            pass
            
    def save_config(self):
        try:
            with open("config.txt", "w") as f:
                f.write(f"{self.app_id}\n{self.app_key}")
        except:
            pass
            
    def show_settings(self):
        dialog = ConfigDialog(self)
        dialog.set_config(self.app_id, self.app_key)
        
        if dialog.exec_() == QDialog.Accepted:
            self.app_id, self.app_key = dialog.get_config()
            self.save_config()
            QMessageBox.information(self, "成功", "API设置已保存")
        
    def process_files(self):
        if not self.app_id or not self.app_key:
            QMessageBox.warning(self, "警告", "请先配置百度翻译API")
            self.show_settings()
            return
            
        if self.file_drop_widget.file_list.count() == 0:
            QMessageBox.warning(self, "警告", "请先拖放文件到窗口中")
            return
            
        self.words_counter = Counter()
        self.result_text.clear()
        
        # 处理所有文件
        for i in range(self.file_drop_widget.file_list.count()):
            file_path = self.file_drop_widget.file_list.item(i).text()
            self.extract_words_from_file(file_path)
            
        # 显示提取的单词统计
        self.result_text.append(f"共提取到 {len(self.words_counter)} 个英文单词")
        
        # 按出现次数排序
        sorted_words = self.words_counter.most_common()
        
        # 开始翻译
        self.start_translation(sorted_words)
        
    def extract_words_from_file(self, file_path):
        try:
            if file_path.lower().endswith('.pdf'):
                self.extract_from_pdf(file_path)
            elif file_path.lower().endswith('.txt'):
                self.extract_from_txt(file_path)
            elif file_path.lower().endswith(('.xlsx', '.xls')):
                self.extract_from_excel(file_path)
                
        except Exception as e:
            self.result_text.append(f"处理文件 {os.path.basename(file_path)} 时出错: {str(e)}")
            
    def extract_from_pdf(self, file_path):
        with open(file_path, 'rb') as file:
            reader = PyPDF2.PdfReader(file)
            for page in reader.pages:
                text = page.extract_text()
                self.extract_english_words(text)
                
    def extract_from_txt(self, file_path):
        with open(file_path, 'r', encoding='utf-8', errors='ignore') as file:
            text = file.read()
            self.extract_english_words(text)
            
    def extract_from_excel(self, file_path):
        wb = load_workbook(file_path)
        for sheet in wb:
            for row in sheet.iter_rows():
                for cell in row:
                    if cell.value and isinstance(cell.value, str):
                        self.extract_english_words(str(cell.value))
                        
    def extract_english_words(self, text):
        # 使用正则表达式提取英文单词
        words = re.findall(r'\b[a-zA-Z]+\b', text)
        for word in words:
            if len(word) > 1:  # 忽略单字母单词
                self.words_counter[word.lower()] += 1
                
    def start_translation(self, word_list):
        self.progress_bar.setVisible(True)
        self.export_btn.setEnabled(False)
        
        self.translation_thread = TranslationThread(word_list, self.app_id, self.app_key)
        self.translation_thread.progress_updated.connect(self.progress_bar.setValue)
        self.translation_thread.translation_finished.connect(self.on_translation_finished)
        self.translation_thread.start()
        
    def on_translation_finished(self, results):
        self.translation_results = results
        self.progress_bar.setVisible(False)
        self.export_btn.setEnabled(True)
        
        # 显示翻译结果
        self.result_text.append("\n翻译结果:")
        for word, translation, count in results:
            self.result_text.append(f"{word} -> {translation} (出现次数: {count})")
            
    def export_to_excel(self):
        if not self.translation_results:
            QMessageBox.warning(self, "警告", "没有可导出的数据")
            return
            
        file_path, _ = QFileDialog.getSaveFileName(
            self, "保存Excel文件", "", "Excel文件 (*.xlsx)"
        )
        
        if file_path:
            try:
                # 创建DataFrame并保存
                df = pd.DataFrame(self.translation_results, 
                                 columns=['英文单词', '中文翻译', '出现次数'])
                df.to_excel(file_path, index=False)
                
                QMessageBox.information(self, "成功", f"数据已导出到 {file_path}")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"导出失败: {str(e)}")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())